﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace EAL.Database
{
    public class BaseList<TItem, TDbContext> 
        : ObservableCollection<TItem>
        where TItem : class, INotifyPropertyChanged
        where TDbContext : System.Data.Entity.DbContext
    {
        private readonly TDbContext _context;


        /// <summary>
        /// ctor receiving a list of items as data source and the data context the item list
        /// was retrieved from
        /// </summary>
        /// <param name="customers">list of item used as data source</param>
        /// <param name="context">data context the item list was retrieved from</param>
        public BaseList(IEnumerable<TItem> items, TDbContext context)
            : base(items)
        {
            this._context = context;

            //subscribe to property changed event of each item in the list
            foreach (TItem item in items)
                item.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(item_PropertyChanged);
        }


        /// <summary>
        /// overridden insert method to add a new item to the list and the underlying data context
        /// </summary>
        /// <param name="index">index to insert the item into the list</param>
        /// <param name="item">item to insert</param>
        protected override void InsertItem(int index, TItem item)
        {
            //add item to data context, too
            this._context.Set<TItem>().Add(item);

            //add item to list itself
            base.InsertItem(index, item);

            //subcribe to property changed event of the newly added item
            item.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(item_PropertyChanged);
        }

        /// <summary>
        /// removes an item from the collection and the data context
        /// </summary>
        /// <param name="index">index of the item to remove</param>
        protected override void RemoveItem(int index)
        {
            //remove item from context ...
            this._context.Set<TItem>().Remove(this.Items[index]);

            //... unsubscribe from property changed event of that item ...
            this.Items[index].PropertyChanged -= item_PropertyChanged;

            //... and remove it from collection itself, too
            base.RemoveItem(index);
        }


        /// <summary>
        /// called when a property of a containing item was changed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void item_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            //call simply base method
            //(the logic exists already, but have to be called manually)
            this.OnPropertyChanged(e);
        }
    }
}
